// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: taekwon

#include <map>

#include <execinfo.h>
#include <gflags/gflags.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

#include "coin2/exchange/base/log/order_logger.h"
#include "coin2/exchange/base/market/enums.h"

DEFINE_string(log_root, "/home/taekwon/data/og_proto_log", "log_root");
DEFINE_string(machine, "hive-83", "machine");
DEFINE_string(start_date, "2020-02-18", "start_date");
DEFINE_string(end_date, "2020-02-22", "end_date");
DEFINE_string(iter, "2000", "iter");
DEFINE_string(owner, "pilot01", "owner");

using coin2::exchange::base::order_util::OrderLogReader;

int main(int argc, char* argv[]) {
  google::InitGoogleLogging(argv[0]);
  gflags::ParseCommandLineFlags(&argc, &argv, true);

  coin::proto::AccountRequestProto req;
  using MarketType = coin::proto::MarketType;
  using ExchangeType = coin::proto::ExchangeType;

  req.set_market_type(coin2::exchange::base::market::MarketTypeToString(MarketType::Futures));
  req.set_exchange(coin2::exchange::base::market::ExchangeTypeToString(ExchangeType::Huobi));
  req.set_owner(FLAGS_owner);

  const size_t BUF_SIZE = 100 * 1024;

  auto begin_ts = TimestampFromString(FLAGS_start_date);
  auto end_ts = TimestampFromString(FLAGS_end_date);

  OrderLogReader reader(req, FLAGS_log_root, FLAGS_machine, begin_ts, end_ts, BUF_SIZE);

  coin::proto::OrderGatewayLog order_log_proto;

  const google::protobuf::EnumDescriptor* descriptor =
      coin::proto::OrderEvent::OrderEventType_descriptor();

  std::map<std::string, int> cnt;
  int i;
  for (i = 0; i < std::stoi(FLAGS_iter); i++) {
    if (!reader.Read(&order_log_proto)) {
      break;
    }

    // LOG(INFO) << order_log_proto.type();
    if (order_log_proto.type() == coin::proto::OrderGatewayLog::BALANCE ||
        order_log_proto.type() == coin::proto::OrderGatewayLog::POSITION) {
      continue;
    }
    if (order_log_proto.type() == coin::proto::OrderGatewayLog::ORDER_EVENT) {
      std::string name = descriptor->FindValueByNumber(order_log_proto.event().type())->name();
      if (cnt.count(name) == 0) {
        cnt[name] = 0;
      }
      cnt[name]++;
      if (order_log_proto.event().type() == coin::proto::OrderEvent::ORDER_FILLED) {
        LOG(INFO) << order_log_proto.DebugString().c_str();
      }
    }
  }
  for (const auto& it : cnt) {
    LOG(INFO) << it.first << ": " << it.second;
  }
  LOG(INFO) << i;
  return 0;
}
